package com.seleniti.enpareja.android.ui.view;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import org.ioc.commons.impl.android.common.util.ArrayAdapterAsList;
import org.ioc.commons.impl.android.common.util.ObservableChange;
import org.ioc.commons.impl.android.common.util.ObservableHashSet;
import org.ioc.commons.impl.android.common.util.SaveInstanceStateHelper;
import org.ioc.commons.impl.android.common.util.SaveInstanceStateHelper.NullBehaviour;
import org.ioc.commons.impl.android.common.util.WrappedFrameLayoutAsEnum;
import org.ioc.commons.impl.android.ui.HasEnabledWrapper;
import org.ioc.commons.impl.android.ui.HasValueWrapper;
import org.ioc.commons.impl.android.ui.HasVisibilityWrapper;
import org.ioc.commons.ui.HasEnabled;
import org.ioc.commons.ui.HasText;
import org.ioc.commons.ui.HasValue;
import org.ioc.commons.ui.HasVisibility;
import org.ioc.commons.ui.impl.HasTextAdapter;
import org.ioc.commons.ui.impl.HasValueAdapter;
import org.ioc.commons.ui.impl.HasVisibilityAdapter;
import org.ioc.commons.ui.impl.OnChangeCommand;
import org.ioc.commons.utils.Format;
import org.ioc.commons.utils.ObjectsCompat;

import android.content.Context;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.support.v7.widget.ShareActionProvider;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationListenerAdapter;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.Checkable;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.ToggleButton;

import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.android.ui.widget.HomeTaskElementDrawable;
import com.seleniti.enpareja.android.ui.widget.PendingMark;
import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.model.integration.database.domain.CoupleType;
import com.seleniti.enpareja.controller.model.integration.database.domain.HomeTask;
import com.seleniti.enpareja.controller.ui.view.HomeTasksView;
import com.seleniti.enpareja.controller.ui.view.HomeTasksView.Action;
import com.seleniti.enpareja.controller.ui.view.HomeTasksView.Event;
import com.seleniti.enpareja.controller.ui.view.HomeTasksView.Operation;
import com.seleniti.enpareja.controller.ui.view.HomeTasksView.Presenter;
import com.seleniti.enpareja.controller.ui.view.HomeTasksViewPresenter;

public class HomeTasksViewWidget extends EnParejaBaseView<Event, Operation, Action, Presenter> implements HomeTasksView {

	private Menu mMenu;
	private boolean loading;
	private boolean enabled;
	private ActionMode actionMode;
	private ToggleButton btnDoneOrPending;
	private ArrayAdapterAsList<HomeTask> aadapter;
	private ListView cellList;
	private final Set<HomeTask> selection = new HashSet<HomeTask>();
	private final ObservableHashSet<String> basicTasksSelection = new ObservableHashSet<String>();
	private SwipeRefreshLayout swipeLayout;
	private PendingMark pendingMark;
	private HomeTask settingsForThis;
	private DatePicker lastTime;
	// private View form;
	// private View list;
	private Button btnMadeByMember1;
	private Button btnMadeByMember2;
	private Button btnMadeByBoth;
	private Button btnCancel;
	private TextView formCaption;
	private Button btnOk;
	// private View basicTasksPanel;
	private ArrayAdapterAsList<String> basicAadapter;
	private ListView basicTasksList;
	private FrameLayout boardPanel;
	private WrappedFrameLayoutAsEnum<Board> boardShown;
	private Button btnAddBasics;
	private Button btnCancelBasics;
	private boolean requiresRefresh = true;
	private View schedulePanel;
	private Button btnSchedule;
	private ImageButton btnCloseSchedulePanel;
	private Button btnScheduleCancel;
	private TextView schedulerFormCaption;
	private DatePicker scheduleDate;
	private TimePicker scheduleTime;
	private Button btnScheduleForMember1;
	private Button btnScheduleForMember2;
	private Button btnScheduleForBoth;

	public HomeTasksViewWidget() {
		super(true);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		this.setHasOptionsMenu(true);
		this.setRetainInstance(true);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		this.presenter = new HomeTasksViewPresenter(this, eventbus, operationManager, actionController);

		if (savedInstanceState != null) {
			SaveInstanceStateHelper ss = new SaveInstanceStateHelper(this.getClass().getName(), savedInstanceState);

			ss.restore().value(NullBehaviour.KEEP_VALUE, this.boardShown()).value(this.loggedUserInfo()).text(this.member1()).text(this.member2()).value(this.couple());
		}

	}

	class HomeTasksStringFormatter implements Format.StringFormatter<HomeTask> {
		@Override
		public String asString(HomeTask obj) {
			return obj != null ? obj.getText() : "";
		}
	}

	private static class ItemViewHolder {

		protected TextView text;
		protected boolean done;
		protected TextView statusInfo;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.home_tasks_view, container, false);

		this.swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
		this.swipeLayout.setOnRefreshListener(new OnRefreshListener() {

			@Override
			public void onRefresh() {
				presenter.onRefreshData();
			}
		});
		this.swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright, android.R.color.holo_green_light,
				android.R.color.holo_orange_light, android.R.color.holo_red_light);

		this.btnDoneOrPending = (ToggleButton) view.findViewById(R.id.btnDoneOrPending);
		this.pendingMark = (PendingMark) view.findViewById(R.id.pendingMark);
		this.lastTime = (DatePicker) view.findViewById(R.id.lastTime);
		this.btnMadeByMember1 = (Button) view.findViewById(R.id.btnMadeByMember1);
		this.btnMadeByMember2 = (Button) view.findViewById(R.id.btnMadeByMember2);
		this.btnMadeByBoth = (Button) view.findViewById(R.id.btnMadeByBoth);
		this.btnOk = (Button) view.findViewById(R.id.btnOk);
		this.btnCancel = (Button) view.findViewById(R.id.btnCancel);
		this.formCaption = (TextView) view.findViewById(R.id.formCaption);
		this.btnAddBasics = (Button) view.findViewById(R.id.btnAddBasics);
		this.btnCancelBasics = (Button) view.findViewById(R.id.btnCancelBasics);

		this.boardPanel = (FrameLayout) view.findViewById(R.id.boardPanel);
		this.boardShown = null;

		// this.list = (View) view.findViewById(R.id.list);
		// this.form = (View) view.findViewById(R.id.form);
		// this.basicTasksPanel = (View)
		// view.findViewById(R.id.basicTasksPanel);
		this.schedulePanel = (View) view.findViewById(R.id.schedulePanel);
		this.btnSchedule = (Button) view.findViewById(R.id.btnSchedule);
		this.btnCloseSchedulePanel = (ImageButton) view.findViewById(R.id.btnCloseSchedulePanel);
		this.scheduleDate = (DatePicker) view.findViewById(R.id.scheduleDate);
		this.scheduleTime = (TimePicker) view.findViewById(R.id.scheduleTime);
		this.scheduleTime.setIs24HourView(true);
		this.btnScheduleForMember1 = (Button) view.findViewById(R.id.btnScheduleForMember1);
		this.btnScheduleForMember2 = (Button) view.findViewById(R.id.btnScheduleForMember2);
		this.btnScheduleForBoth = (Button) view.findViewById(R.id.btnScheduleForBoth);
		this.btnScheduleCancel = (Button) view.findViewById(R.id.btnScheduleCancel);
		this.schedulerFormCaption = (TextView) view.findViewById(R.id.schedulerFormCaption);

		this.btnDoneOrPending.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				presenter.onDoneOrPendingButtonToggled();
			}
		});

		this.btnMadeByMember1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onMarkSelectedAsMadeByMember1();
			}
		});

		this.btnMadeByMember2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onMarkSelectedAsMadeByMember2();
			}
		});

		this.btnMadeByBoth.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onMarkSelectedAsMadeByBoth();
			}
		});

		this.btnOk.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onMarkSelectedAsMadeByMember1();
			}
		});

		this.btnCancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideTaskDoneSettings();
			}
		});

		this.btnAddBasics.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onAddSelectedBasicElements();
			}
		});

		this.btnCancelBasics.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onCancelAddingSelectedBasicElements();
			}
		});

		this.btnSchedule.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onScheduleSuggestion();
			}
		});

		this.btnCloseSchedulePanel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onHideScheduleSuggestion();
			}
		});

		this.btnScheduleForMember1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onScheduleSuggestedForMember1();
			}
		});

		this.btnScheduleForMember2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onScheduleSuggestedForMember2();
			}
		});

		this.btnScheduleForBoth.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				presenter.onScheduleSuggestedForBoth();
			}
		});

		this.btnScheduleCancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				hideScheduleForm();
			}
		});

		initHomeTasksList(view);
		initBasicTasksList(view);

		return view;
	}

	@Override
	public void hideScheduleForm() {
		presenter.onHideScheduleForm();
	}

	protected void initHomeTasksList(View view) {
		this.cellList = (ListView) view.findViewById(R.id.cellList);
		this.cellList.setEmptyView(view.findViewById(R.id.empty));
		Context context = this.getContext();
		if (this.aadapter == null || !ObjectsCompat.equals(this.aadapter.getContext(), this.getContext())) {

			List<HomeTask> objects = (this.aadapter == null) ? new ArrayList<HomeTask>() : this.aadapter;

			this.aadapter = new ArrayAdapterAsList<HomeTask>(context, R.layout.home_tasks_done_element, objects) {
				@Override
				public View getView(int position, View convertView, ViewGroup parent) {
					ItemViewHolder ivh = null;
					LinearLayout panel = null;
					final HomeTask item = this.getItem(position);
					boolean done = (item != null && item.getLastTime() != null);

					if (convertView == null) {
						Bundle savedInstanceState = new Bundle();
						LayoutInflater inflater = getLayoutInflater(savedInstanceState);
						ivh = new ItemViewHolder();

						if (actionMode == ActionMode.DELETE_ELEMENT) {
							convertView = inflater.inflate(android.R.layout.simple_list_item_multiple_choice, parent,
									false);

							CheckedTextView ctv = (CheckedTextView) convertView;

							ivh.text = ctv;

						} else if (done) {
							convertView = inflater.inflate(R.layout.home_tasks_done_element, parent, false);
						} else {
							convertView = inflater.inflate(R.layout.home_tasks_pending_element, parent, false);
						}

						if (convertView instanceof LinearLayout) {
							panel = (LinearLayout) convertView;

							ivh.text = (TextView) panel.findViewById(R.id.caption);
							ivh.statusInfo = (TextView) panel.findViewById(R.id.statusInfo);

							panel.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
									MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

							int ps = panel.getPaddingLeft();
							int pe = panel.getPaddingRight();
							int pt = panel.getPaddingTop();
							int pb = panel.getPaddingBottom();

							int padding = Math.max(Math.max(Math.max(ps, pe), pt), pb);

							int minH = panel.getMeasuredHeight() - (padding * 2);

							HomeTaskElementDrawable drw = new HomeTaskElementDrawable(done);
							drw.setMinHeight(minH);

							ivh.text.setBackground(drw);
						}
						ivh.done = done;

						convertView.setTag(ivh);
					} else {
						// panel = (LinearLayout) convertView;
						ivh = (ItemViewHolder) convertView.getTag();

						if (item != null && ivh.done != done) {
							return getView(position, null, parent);
						}
					}

					String text = item != null ? item.getText() : "--";

					ivh.text.setText(text);

					if (ivh.statusInfo != null) {
						String statusInfo = getStatusInfo(item);

						ivh.statusInfo.setText(statusInfo);
					}

					return convertView;
				}
			};
		}

		this.aadapter.registerDataSetObserver(new DataSetObserver() {

			@Override
			public void onChanged() {
				super.onChanged();

				if (getActivity() != null) {
					setShareIntent(new SetShareIntentParameter<HomeTask>(getPending(aadapter),
							new HomeTasksStringFormatter(), getString(R.string.home_tasks) + " ("
									+ getString(R.string.pending) + ")"));
				}
			}
		});

		this.cellList.setAdapter(aadapter);
		this.cellList.setChoiceMode(ListView.CHOICE_MODE_NONE);
		this.cellList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				if (actionMode != null) {
					HomeTask value = (HomeTask) cellList.getItemAtPosition(position);
					switch (actionMode) {
					case MODIFY_ELEMENT:
						modifyElement(value);
						break;
					case SWITCH_LIST:
						switchElementFromList(value);
						break;
					case DELETE_ELEMENT:
						boolean selected = !cellList.isItemChecked(position);
						cellList.setItemChecked(position, selected);

						if (selected) {
							selection.add((HomeTask) cellList.getItemAtPosition(position));
						} else {
							selection.remove((HomeTask) cellList.getItemAtPosition(position));
						}

						presenter.onSelectionChanged();
						break;
					default:
						/*
						 * Nothing to do
						 */
					}
				}
			}
		});

		// Capture ListView item click
		this.cellList.setMultiChoiceModeListener(new MultiChoiceModeListener() {

			@Override
			public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
				return false;
			}

			@Override
			public void onDestroyActionMode(android.view.ActionMode mode) {

			}

			@Override
			public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {

			}

		});
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);

		inflater.inflate(R.menu.home_tasks_menu, menu);

		this.mMenu = menu;

		// MenuItem btnAdd = mMenu.findItem(R.id.add_item);
		MenuItem btnModify = mMenu.findItem(R.id.modify_item);
		MenuItem btnDelete = mMenu.findItem(R.id.delete_item);
		// Locate MenuItem with ShareActionProvider
		MenuItem btnShare = menu.findItem(R.id.menu_item_share);

		// Fetch and store ShareActionProvider
		this.mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(btnShare);
		setShareIntent(new SetShareIntentParameter<HomeTask>(getPending(this.aadapter), new HomeTasksStringFormatter(),
				getString(R.string.home_tasks) + " (" + getString(R.string.pending) + ")"));
		btnShare.setVisible(this.mShareActionProvider != null);

		btnModify.setChecked(this.actionMode == ActionMode.MODIFY_ELEMENT);
		btnModify.setIcon(btnModify.isChecked() ? R.drawable.modify_icon_on : R.drawable.modify_icon);

		btnDelete.setChecked(this.actionMode == ActionMode.DELETE_ELEMENT);
		btnDelete.setIcon(btnDelete.isChecked() ? R.drawable.bin_icon_on : R.drawable.bin_icon);

	}

	private List<HomeTask> getPending(List<HomeTask> list) {
		List<HomeTask> result = null;
		if (list != null) {
			result = new ArrayList<HomeTask>(list.size());

			for (HomeTask t : list) {
				if (t.getLastTime() == null) {
					result.add(t);
				}
			}
		}
		return result;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.add_item:
			this.setActionMode(ActionMode.SWITCH_LIST);
			this.addNewElement();
			return true;
		case R.id.modify_item:
			presenter.onModifyButtonToggled(this.getActionMode() != ActionMode.MODIFY_ELEMENT);
			return true;
		case R.id.delete_item:
			this.setActionMode(this.getActionMode() != ActionMode.DELETE_ELEMENT ? ActionMode.DELETE_ELEMENT
					: ActionMode.SWITCH_LIST);
			return true;
		case R.id.basic_tasks_item:
			this.showBasics();
			return true;
		default:
			this.setActionMode(ActionMode.SWITCH_LIST);
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void setLoading(boolean loading) {
		this.loading = loading;
		if (mMenu != null) {
			MenuItem btnAdd = mMenu.findItem(R.id.add_item);
			MenuItem btnModify = mMenu.findItem(R.id.modify_item);
			MenuItem btnDelete = mMenu.findItem(R.id.delete_item);

			btnAdd.setEnabled(!loading);
			btnModify.setEnabled(!loading);
			btnDelete.setEnabled(!loading);
		}

		if (this.swipeLayout != null) {
			this.swipeLayout.setRefreshing(loading);
		}
	}

	@Override
	public boolean isLoading() {
		return this.loading;
	}

	@Override
	public boolean isEnabled() {
		return this.enabled;
	}

	@Override
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
		if (mMenu != null) {
			MenuItem btnAdd = mMenu.findItem(R.id.add_item);
			MenuItem btnModify = mMenu.findItem(R.id.modify_item);
			MenuItem btnDelete = mMenu.findItem(R.id.delete_item);

			HasEnabledWrapper.setEnabled(enabled, btnAdd, btnDelete, btnModify);
		}
	}

	@Override
	public void setActionMode(ActionMode mode) {
		boolean changed = !ObjectsCompat.equals(this.actionMode, mode);
		ActionMode prevMode = mode;
		boolean requiresRepaint = (prevMode == ActionMode.DELETE_ELEMENT && actionMode != ActionMode.DELETE_ELEMENT)
				|| (prevMode != ActionMode.DELETE_ELEMENT && actionMode == ActionMode.DELETE_ELEMENT);
		this.actionMode = mode;

		if (mode != null) {
			switch (mode) {
			case SWITCH_LIST:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_NONE);
				break;
			case DELETE_ELEMENT:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
				break;
			case MODIFY_ELEMENT:
				this.cellList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
				break;
			}
		}

		if (this.getActivity() != null) {
			this.getActivity().invalidateOptionsMenu();
		}

		if (requiresRepaint && this.cellList != null) {
			this.saveScrollPosition(cellList);

			/*
			 * Clear all recycled views, so they will be repainted properly
			 */
			this.cellList.setAdapter(aadapter);

			this.restoreScrollPosition(cellList);
		}

		if (changed) {
			this.presenter.onActionModeChanged();
		}

	}

	@Override
	public ActionMode getActionMode() {
		return this.actionMode;
	}

	@Override
	public void addNewElement() {
		this.presenter.onAddNewElement();
	}

	@Override
	public void modifyElement(HomeTask element) {
		this.presenter.onModifyElement(element);
	}

	@Override
	public HasValue<Boolean> onlyPendingFilter() {
		return HasValueWrapper.from((Checkable) btnDoneOrPending, this);
	}

	@Override
	public List<HomeTask> homeTasksList() {
		return this.aadapter;
	}

	@Override
	public Set<HomeTask> getSelection() {
		return this.selection;
	}

	@Override
	public void switchElementFromList(HomeTask value) {
		presenter.onSwitchElementFromList(value);
	}

	@Override
	public HasValue<Integer> pendingCounter() {
		return this.pendingMark;
	}

	@Override
	public void scrollToElement(int idx) {
		cellList.smoothScrollToPosition(idx);
	}

	@Override
	public void markSelectedAsMadeByMember1() {
		this.presenter.onMarkSelectedAsMadeByMember1();
	}

	@Override
	public void markSelectedAsMadeByMember2() {
		this.presenter.onMarkSelectedAsMadeByMember2();
	}

	@Override
	public void markSelectedAsMadeByBoth() {
		this.presenter.onMarkSelectedAsMadeByBoth();
	}

	@Override
	public HomeTask getSettingsForThis() {
		return this.settingsForThis;
	}

	@Override
	public HasValue<Date> lastTime() {
		return HasValueWrapper.from(this.lastTime, this);
	}

	@Override
	public void hideTaskDoneSettings() {
		this.boardShown().setValue(Board.TASKS_LIST);
	}

	@Override
	public void showTaskDoneSettings(HomeTask settingsForThis, boolean changeDate) {
		this.settingsForThis = settingsForThis;
		this.boardShown().setValue(Board.FORM);
	}

	@Override
	public HasText member1() {
		return HasTextAdapter.forField("member1", this).onChange(new OnChangeCommand<String>() {

			@Override
			public void execute(String value) {
				btnMadeByMember1.setText(value);
				btnScheduleForMember1.setText(value);
			}
		});
		// return HasTextWrapper.from(btnMadeByMember1, this);
	}

	@Override
	public HasText member2() {
		return HasTextAdapter.forField("member2", this).onChange(new OnChangeCommand<String>() {

			@Override
			public void execute(String value) {
				btnMadeByMember2.setText(value);
				btnScheduleForMember2.setText(value);
			}
		});
		// return HasTextWrapper.from(btnMadeByMember2, this);
	}

	@Override
	public HasValue<Board> boardShown() {
		if (this.boardShown == null) {
			this.boardShown = new WrappedFrameLayoutAsEnum<HomeTasksView.Board>(this.boardPanel,
					HomeTasksView.Board.values());
			// TODO: Slide effect
		}

		return this.boardShown;
	}

	@Override
	public boolean goBoardBack() {
		if (boardShown().getValue() == Board.FORM) {
			hideTaskDoneSettings();
			return true;
		}

		return false;
	}

	protected String getStatusInfo(final HomeTask item) {
		String statusInfo = null;

		if (item != null) {
			if (item.getLastTime() != null) {
				if (item.getMadeBy() != null) {
					String madeBy = "--";
					switch (item.getMadeBy()) {
					case BOTH:
						madeBy = "ambos";
						break;
					case MEMBER_1:
						madeBy = member1().getText() != null ? member1().getText() : "tí";
						break;
					case MEMBER_2:
						madeBy = member2().getText() != null ? member2().getText() : "tu pareja";
						break;
					}
					statusInfo = Format.substitute("Hecho por {0} el {1}", madeBy,
							DateFormat.getDateInstance().format(item.getLastTime()));
				} else {
					statusInfo = Format.substitute("Hecho el {0}",
							DateFormat.getDateInstance().format(item.getLastTime()));
				}
			} else {
				statusInfo = "Pendiente";
			}
		} else {
			statusInfo = "";
		}
		return statusInfo;
	}

	@Override
	public HasValue<CoupleType> coupleType() {
		return HasValueAdapter.forField("coupleType", this, CoupleType.USERS_COUPLE).onChange(
				new OnChangeCommand<CoupleType>() {

					@Override
					public void execute(CoupleType value) {
						if (value == null) {
							value = CoupleType.USERS_COUPLE;
						}
						switch (value) {
						case USERS_COUPLE:
							formCaption.setText(R.string.made_by_semicolon);
							HasVisibilityWrapper.setVisible(true, btnMadeByMember1, btnMadeByMember2, btnMadeByBoth);
							btnOk.setVisibility(View.GONE);
							break;
						case SINGLE_USER:
						case TESTING_MODE_COUPLE:
							formCaption.setText(R.string.made_semicolon);
							HasVisibilityWrapper.setVisible(false, btnMadeByMember1, btnMadeByMember2, btnMadeByBoth);
							btnOk.setVisibility(View.VISIBLE);
							break;
						default:
							throw new IllegalArgumentException("Unknow type: " + value);
						}

					}
				});
	}

	@Override
	public void showBasics() {
		presenter.onShowBasics();
	}

	protected void initBasicTasksList(View view) {
		this.basicTasksList = (ListView) view.findViewById(R.id.basicTasksList);

		Context context = this.getContext();
		if (this.basicAadapter == null || !ObjectsCompat.equals(this.basicAadapter.getContext(), this.getContext())) {

			List<String> objects = (this.basicAadapter == null) ? new ArrayList<String>() : this.basicAadapter;

			this.basicAadapter = new ArrayAdapterAsList<String>(context,
					android.R.layout.simple_list_item_multiple_choice, objects) {
				@Override
				public View getView(int position, View convertView, ViewGroup parent) {
					ItemViewHolder ivh = null;
					final String text = this.getItem(position);

					if (convertView == null) {
						Bundle savedInstanceState = new Bundle();
						LayoutInflater inflater = getLayoutInflater(savedInstanceState);
						ivh = new ItemViewHolder();

						convertView = inflater
								.inflate(android.R.layout.simple_list_item_multiple_choice, parent, false);

						CheckedTextView ctv = (CheckedTextView) convertView;

						ivh.text = ctv;

						convertView.setTag(ivh);
					} else {
						// panel = (LinearLayout) convertView;
						ivh = (ItemViewHolder) convertView.getTag();
					}

					ivh.text.setText(text);

					return convertView;
				}
			};
		}

		this.basicTasksList.setAdapter(this.basicAadapter);
		this.basicTasksList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		this.basicTasksList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				boolean selected = basicTasksList.isItemChecked(position);
				// basicTasksList.setItemChecked(position, selected);

				boolean previous = HomeTasksViewWidget.this.requiresRefresh;
				HomeTasksViewWidget.this.requiresRefresh = false;
				if (selected) {
					basicTasksSelection.add((String) basicTasksList.getItemAtPosition(position));
				} else {
					basicTasksSelection.remove((String) basicTasksList.getItemAtPosition(position));
				}
				HomeTasksViewWidget.this.requiresRefresh = previous;
			}
		});
		this.basicTasksSelection.addObserver(new Observer() {

			@Override
			public void update(Observable observable, final Object data) {
				if (HomeTasksViewWidget.this.requiresRefresh) {
					HomeTasksViewWidget.this.requiresRefresh = false;
					new Handler().post(new Runnable() {

						@Override
						public void run() {
							ObservableChange oc = (ObservableChange) data;
							@SuppressWarnings("unchecked")
							Collection<String> elements = (Collection<String>) oc.getElements();

							for (String element : elements) {
								int idx = basicAadapter.indexOf(element);
								if (idx >= 0) {
									switch (oc.getOperation()) {
									case Add:
										basicTasksList.setItemChecked(idx, true);
										// child.setChecked(true);
										break;
									case Remove:
										basicTasksList.setItemChecked(idx, false);
										// child.setChecked(false);
										break;
									default:
										/*
										 * Nothing to do
										 */
									}
								}
							}
							HomeTasksViewWidget.this.requiresRefresh = true;
						}
					});
				}

			}
		});

		// Capture ListView item click
		this.basicTasksList.setMultiChoiceModeListener(new MultiChoiceModeListener() {

			@Override
			public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
				return false;
			}

			@Override
			public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
				return false;
			}

			@Override
			public void onDestroyActionMode(android.view.ActionMode mode) {

			}

			@Override
			public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {

			}

		});
	}

	@Override
	public List<String> basicTasks() {
		return this.basicAadapter;
	}

	@Override
	public Set<String> selectedBasicTasks() {
		return this.basicTasksSelection;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		SaveInstanceStateHelper ss = new SaveInstanceStateHelper(this.getClass().getName(), outState);

		ss.save().value(this.boardShown()).value(this.loggedUserInfo()).text(this.member1()).text(this.member2()).value(this.couple());
	}

	@Override
	public HasValue<LoggedUserInfo> loggedUserInfo() {
		return HasValueAdapter.<LoggedUserInfo> forField("loggedUserInfo", this);
	}

	@Override
	public HasText scheduleSuggestionText() {
		return HasTextAdapter.forField("scheduleSuggestionText", this).onChange(new OnChangeCommand<String>() {

			@Override
			public void execute(String value) {
				btnSchedule.setText(value);
				schedulerFormCaption.setText(value);
			}
		});
	}

	@Override
	public HasVisibility scheduleSuggestionVisibility() {
		return HasVisibilityAdapter.forField("scheduleSuggestionVisibility", this,
				this.schedulePanel.getVisibility() == View.VISIBLE).onChange(new OnChangeCommand<Boolean>() {

			@Override
			public void execute(Boolean value) {
				boolean visible = Boolean.TRUE.equals(value);

				if (visible) {
					Animation slideUp = AnimationUtils.loadAnimation(getContext(), R.anim.slide_up);
					slideUp.setFillAfter(true);
					schedulePanel.setVisibility(View.VISIBLE);
					schedulePanel.startAnimation(slideUp);
				} else {
					Animation slideDown = AnimationUtils.loadAnimation(getContext(), R.anim.slide_down);
					slideDown.setAnimationListener(new AnimationListenerAdapter() {

						@Override
						public void onAnimationEnd(Animation animation) {
							schedulePanel.setVisibility(View.GONE);
						}
					});
					slideDown.setFillAfter(true);
					schedulePanel.setVisibility(View.VISIBLE);
					schedulePanel.startAnimation(slideDown);
				}

			}
		});
		// return HasVisibilityWrapper.from(this.schedulePanel, this);
	}
	
	@Override
	public HasEnabled scheduleSuggestionEnabled() {
		return HasEnabledWrapper.from(btnSchedule, this);
	}

	@Override
	public HasValue<Date> scheduleDate() {
		return HasValueWrapper.from(scheduleDate, this);
	}

	@Override
	public HasValue<Date> scheduleTime() {
		return HasValueWrapper.from(scheduleTime, this);
	}
}
